using System;
using System.Globalization;
using Sharp2City;
using Wolfpack.Core;
using Wolfpack.Core.Checks;
using Wolfpack.Core.Interfaces.Entities;
using Wolfpack.Core.Notification;

namespace Wolfpack.Contrib.BuildAnalytics.Checks.TeamCity
{
    public class TeamCityBuildNotificationCheck : HealthCheckBase<TeamCityBuildNotificationCheckConfig>
    {
        private int _lastBuildId;

        /// <summary>
        /// default ctor
        /// </summary>
        public TeamCityBuildNotificationCheck(TeamCityBuildNotificationCheckConfig config)
            : base(config)
        {
        }

        public override void Initialise()
        {
        }

        public override void Execute()
        {
            Logger.Debug("TeamCityBuildNotificationCheck inspecting {0}/{1}", _config.ProjectName, _config.ConfigurationName);

            var tc = new TeamCityClient(_config.BuildServerUrl,
                                        _config.UserId, _config.Password,
                                        _config.UseSsl, _config.TrustDuffSslCertificate);
            var build = tc.GetLastBuild(tc.FindBuildConfiguration(_config.ProjectName, _config.ConfigurationName));

            if (build.BuildId == _lastBuildId)
                return;

            // new build, publish it
            _lastBuildId = build.BuildId;
            var buildResult = (build.BuildStatus == BuildStatus.Success);

            Logger.Debug("\tBuild {0} for '{1}/{2}' has been detected (Success:={3})", 
                _lastBuildId, 
                _config.ProjectName, _config.ConfigurationName,
                buildResult);
            
            var duration = build.FinishDate.Subtract(build.StartDate);

            var data = HealthCheckData.For(Identity,
                                           "Status of build '{0}' for project '{1}: {2}",
                                           _config.ConfigurationName, _config.ProjectName,
                                           build.StatusText)
                .ResultIs(buildResult)
                .ResultCountIs(duration.TotalSeconds)
                .SetDuration(duration)
                .SetGeneratedOnUtc(build.FinishDate)
                .AddTag(_lastBuildId.ToString(CultureInfo.InvariantCulture))
                .AddProperty(NotificationProperties.BuildId, _lastBuildId.ToString(CultureInfo.InvariantCulture))
                .AddProperty(NotificationProperties.ProjectName, _config.ProjectName)
                .AddProperty(NotificationProperties.ConfigurationName, _config.ConfigurationName);

            Publish(NotificationRequestBuilder.For(_config.NotificationMode, data, 
                UseProjectBuildConfigAsUniqueKey).Build());
        }

        private static void UseProjectBuildConfigAsUniqueKey(NotificationRequest notificationRequest)
        {
            notificationRequest.DataKeyGenerator = request => string.Format("{0}_{1}.{2}", 
                request.CheckId,
                request.Properties[NotificationProperties.ProjectName],
                request.Properties[NotificationProperties.ConfigurationName]);
        }

        protected override PluginDescriptor BuildIdentity()
        {
            return new PluginDescriptor
                       {
                           Description = "Detects new TeamCity builds and reports on their state",
                           TypeId = new Guid("040CF1F2-7000-4902-86EA-7E348E2EEC2C"),
                           Name = _config.FriendlyId
                       };
        }
    }
}